package org.apache.flink.runtime.resourceconsumer;

import java.util.UUID;
import java.util.concurrent.CompletableFuture;

import javax.annotation.Nonnull;

import org.apache.flink.runtime.resourceconsumer.runner.ResourceConsumerRunnerResult;
import org.apache.flink.util.AutoCloseableAsync;
import org.apache.flink.util.ERException;
import org.apache.flink.util.concurrent.FutureUtils;

/**
 * @类名: ResourceConsumerServiceProcess
 * @说明: 资源消费者服务处理
 *
 * @author   leehom
 * @Date	 2023年11月1日 下午2:22:26
 * 修改记录：
 *
 * @see 	 
 */
/** 
 * ResourceConsumerServiceProcess is responsible for running a {@link ResourceConsumerService}. 
 * ResourceConsumer是ResourceConsumerService的实现
 */
public interface ResourceConsumerServiceProcess extends AutoCloseableAsync {

    static ResourceConsumerServiceProcess waitingForLeadership() {
        return WaitingForLeadership.INSTANCE;
    }

    /** The leader session id of this process. */
    UUID getLeaderSessionId();

    /** True iff the {@link JobMasterService} has been initialized and is running. */
    boolean isInitializedAndRunning();

    /**
     * Future which is completed with the {@link ResourceConsumerGateway} once the {@link ResourceConsumerService}
     * has been created. Upon closing of the process, this future is completed exceptionally if it
     * is still uncompleted.
     */
    CompletableFuture<ResourceConsumerGateway> getResourceConsumerGatewayFuture();

    /**
     * Future which is completed with the result of job execution. The job's result can be the
     * {@link JobManagerRunnerResult}, {@link ConsumeNotFinishedException} if the job was not finished
     * or an {@link Throwable} if an unexpected failure occurs. Upon closing of the process, this
     * future is completed exceptionally with {@link ConsumeNotFinishedException}.
     */
    CompletableFuture<ResourceConsumerRunnerResult> getResultFuture();

    /** Future which is completed with the {@link ResourceConsumerService} address once it is created. */
    CompletableFuture<String> getLeaderAddressFuture();
    
    //
    enum WaitingForLeadership implements ResourceConsumerServiceProcess {
        INSTANCE;

        @Override
        public CompletableFuture<Void> closeAsync() {
            return FutureUtils.completedVoidFuture();
        }

        @Override
        public UUID getLeaderSessionId() {
            throw new UnsupportedOperationException("Still waiting for the leadership.");
        }

        @Override
        public boolean isInitializedAndRunning() {
            return false;
        }

        @Override
        public CompletableFuture<ResourceConsumerGateway> getResourceConsumerGatewayFuture() {
            return failedOperationFuture();
        }

        @Override
        public CompletableFuture<ResourceConsumerRunnerResult> getResultFuture() {
            return failedOperationFuture();
        }

        @Override
        public CompletableFuture<String> getLeaderAddressFuture() {
            return failedOperationFuture();
        }

        @Nonnull
        private <T> CompletableFuture<T> failedOperationFuture() {
            return FutureUtils.completedExceptionally(
                    new ERException("Still waiting for the leadership."));
        }
    }
}
